home *** CD-ROM | disk | FTP | other *** search
/ Night Owl 8 / Night Owl CD-ROM (NOPV8) (Night Owl Publisher) (1993).ISO / 047a / lex_yacc.arj / PASLEX.L < prev    next >
Text File  |  1990-01-14  |  5KB  |  173 lines

  1. %{
  2. (*
  3.  * scan.l
  4.  *
  5.  * lex input file for pascal scanner
  6.  *
  7.  * extensions: to ways to spell "external" and "->" ok for "^".
  8.  *
  9.  * - PasLex.l: adapted to Turbo Pascal Lex 2-28-89 AG
  10.  *   Note: keywords are determined by scanning a keyword table, rather
  11.  *   than including the keyword patterns in the Lex source which is done
  12.  *   in the original version of this file. The main reason for this is,
  13.  *   that the DFA table generated from the original spec grows too large
  14.  *   to be compilable by Turbo Pascal (Lex will construct the table,
  15.  *   but Turbo Pascal puts it into the static data segment which holds
  16.  *   all typed constants and global variables, and this data segment is
  17.  *   64 KB max.).
  18.  *)
  19.  
  20. unit PasLex;
  21. interface
  22. uses LexLib, YaccLib;
  23. {$I Pas.h}
  24. var
  25.   infile : string;
  26.   line_no : integer;
  27. function yylex : integer;
  28. function act_token : string;
  29. implementation
  30. const newline = #10;
  31. procedure commenteof;
  32.   begin
  33.     writeln('unexpected EOF inside comment at line ', line_no);
  34.   end(*commenteof*);
  35. function is_keyword(id : string; var token : integer) : boolean; 
  36.   (* checks whether id is Pascal keyword; if so, returns corresponding
  37.      token number in token *)
  38.   forward;
  39. %}
  40.  
  41. NQUOTE    [^']
  42.  
  43. %%
  44.  
  45.  var
  46.    c : char;
  47.    kw : integer;
  48.  
  49. [a-zA-Z]([a-zA-Z0-9])*    if is_keyword(yytext, kw) then
  50.                           return(kw)
  51.                         else
  52.                           return(IDENTIFIER);
  53.  
  54. ":="            return(ASSIGNMENT);
  55. '({NQUOTE}|'')+'    return(CHARACTER_STRING);
  56. ":"            return(COLON);
  57. ","            return(COMMA);
  58. [0-9]+            return(DIGSEQ);
  59. "."            return(DOT);
  60. ".."            return(DOTDOT);
  61. "="            return(EQUAL);
  62. ">="            return(GE);
  63. ">"            return(GT);
  64. "["            return(LBRAC);
  65. "<="            return(LE);
  66. "("            return(LPAREN);
  67. "<"            return(LT);
  68. "-"            return(MINUS);
  69. "<>"            return(NOTEQUAL);
  70. "+"            return(PLUS);
  71. "]"            return(RBRAC);
  72. [0-9]+"."[0-9]+        return(REALNUMBER);
  73. ")"            return(RPAREN);
  74. ";"            return(SEMICOLON);
  75. "/"            return(SLASH);
  76. "*"            return(STAR);
  77. "**"            return(STARSTAR);
  78. "->"                |
  79. "^"            return(UPARROW);
  80.  
  81. "(*"                |
  82. "{"            begin
  83.               repeat
  84.                 c := input;
  85.                 case c of
  86.                   '}' : exit;
  87.                   '*' : begin
  88.                       c := input;
  89.                       if c=')' then exit else unput(c)
  90.                     end;
  91.                   newline : inc(line_no);
  92.                               #0 : commenteof;
  93.                 end;
  94.               until false
  95.                         end;
  96. [ \t\f]            ;
  97.  
  98. \n            inc(line_no);
  99.  
  100. .            writeln('''', yytext[1], ''' (#', ord(yytext[1]),
  101.               '): illegal character at line ', line_no);
  102.  
  103. %%
  104.  
  105. function upper(id : string) : string;
  106.   var i : integer;
  107.   begin
  108.     for i := 1 to length(id) do
  109.       id[i] := upCase(id[i]);
  110.     upper := id
  111.   end(*upper*);
  112. function is_keyword(id : string; var token : integer) : boolean;
  113.   const
  114.     id_len = 20;
  115.   type
  116.     Ident = string[id_len];
  117.   const
  118.     (* table of Pascal keywords: *)
  119.     no_of_keywords = 39;
  120.     keyword : array [1..no_of_keywords] of Ident = (
  121.       'AND',       'ARRAY',     'BEGIN',    'CASE',
  122.       'CONST',     'DIV',       'DO',       'DOWNTO',
  123.       'ELSE',      'END',       'EXTERNAL', 'EXTERN',
  124.       'FILE',      'FOR',       'FORWARD',  'FUNCTION',
  125.       'GOTO',      'IF',        'IN',       'LABEL',
  126.       'MOD',       'NIL',       'NOT',      'OF',
  127.       'OR',        'OTHERWISE', 'PACKED',   'PROCEDURE',
  128.       'PROGRAM',   'RECORD',    'REPEAT',   'SET',
  129.       'THEN',      'TO',        'TYPE',     'UNTIL',
  130.       'VAR',       'WHILE',     'WITH');
  131.     keyword_token : array [1..no_of_keywords] of integer = (
  132.       _AND,        _ARRAY,      _BEGIN,     _CASE,
  133.       _CONST,      _DIV,        _DO,        _DOWNTO,
  134.       _ELSE,       _END,        _EXTERNAL,  _EXTERNAL,
  135.                                 (* EXTERNAL: 2 spellings (see above)! *)
  136.       _FILE,       _FOR,        _FORWARD,   _FUNCTION,
  137.       _GOTO,       _IF,         _IN,        _LABEL,
  138.       _MOD,        _NIL,        _NOT,       _OF,
  139.       _OR,         _OTHERWISE,  _PACKED,    _PROCEDURE,
  140.       _PROGRAM,    _RECORD,     _REPEAT,    _SET,
  141.       _THEN,       _TO,         _TYPE,      _UNTIL,
  142.       _VAR,        _WHILE,      _WITH);
  143.   var m, n, k : integer;
  144.   begin
  145.     id := upper(id);
  146.     m := 1; n := no_of_keywords;
  147.     while m<=n do
  148.       begin
  149.         k := m+(n-m) div 2;
  150.         if id=keyword[k] then
  151.           begin
  152.             is_keyword := true;
  153.             token := keyword_token[k];
  154.             exit
  155.           end
  156.         else if id>keyword[k] then
  157.           m := k+1
  158.         else
  159.           n := k-1
  160.       end;
  161.     is_keyword := false
  162.   end(*is_keyword*);
  163. function act_token : string;
  164.   begin
  165.     act_token := yytext
  166.   end(*act_token*);
  167. begin
  168.   write('input file: ');
  169.   readln(infile);
  170.   line_no := 1;
  171.   assign(yyin, infile);
  172.   reset(yyin);
  173. end.